package com.cyou.qb.front.aspect;

import java.util.Arrays;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cyou.qb.common.dao.UserOperationLogDao;
import com.cyou.qb.common.domain.UserOperationLog;
import com.cyou.qb.service.BaseService;
import com.cyou.qb.system.FrontUserContext;
import com.cyou.qb.system.ServiceContext;
import com.cyou.qb.system.SpringMvcUtils;
import com.cyou.qb.system.UserContext;
/**
 *   1 	运行方法过程中的异常处理; 2	运行方法后的日志记录
 * @author luzhaoman
 *
 *  前台用不上
 */
@Deprecated
public class ServiceMethodAspect {

	private static Log logger = LogFactory.getLog(ServiceMethodAspect.class);

	/**
	 * 用来记录操作日志
	 */
	@Autowired
	private UserOperationLogDao userOperationLogDao;

	/**
	 * 增加aop切入点
	 */
	@Pointcut("execution(* com.cyou.qb.common.service.impl.*ServiceImpl.*(..))")
	public void servicePointcut() {
		//System.out.println("aop");
	}

	/**
	 * @param jp
	 * @throws Exception
	 *             负责处理：  1 	运行方法过程中的异常处理; 2	运行方法后的日志记录
	 */
	@SuppressWarnings({"rawtypes" })
	@Around("servicePointcut()")
	public Object doAroundPointcut(ProceedingJoinPoint jp) throws Exception {

		String packageName = jp.getTarget().getClass().getPackage().getName();
		Class clazz = jp.getTarget().getClass();
		String className = clazz.getName().replaceAll(packageName + ".", "").split("\\$\\$")[0];
		String execution = jp.toShortString();
		String methodName = execution.substring(10, execution.length() - 1);
		if(methodName.indexOf("(")>=0){
			methodName=methodName.substring(0,methodName.indexOf("("));
		}
		String[] tmp = methodName.split("\\.");
		if(tmp.length==1){
			methodName=tmp[0];
		}else{
			methodName=tmp[tmp.length-1];
		}
		String method = className + "." + methodName;

		if (logger.isDebugEnabled()) {
			logger.debug(packageName + " : " + methodName + " : " + method);
		}
		BaseService service = (BaseService) (jp.getTarget());
		
		UserContext userContext = SpringMvcUtils.getUserContext();
		if (null == userContext) {
			userContext = FrontUserContext.getDefault(); 
		}
		ServiceContext serviceContext = new ServiceContext();
		serviceContext.setUserContext(userContext);
		// 2 运行方法前的上下文信息获取
		serviceContext.setOperationMethod(method);
		service.setServiceContext(serviceContext);
		// 3 运行方法过程中的异常处理
		Object result = null;

		try {
			result = jp.proceed();
		} catch (Throwable e) {
			String param= Arrays.toString(jp.getArgs());
			if(param.length()>100){
				param=param.substring(0,100)+"..";
			}
			logger.warn("service mothod: " + method + "\t param:" +param);
			throw new RuntimeException(e.getMessage(),e);
		}
		// 4 运行方法后的日志记录
		try {
			List<UserOperationLog> logList = service.getServiceContext().getLogList();
			if(logList!=null){
				for (UserOperationLog userOperationLog : logList) {
					if(userOperationLog!=null){
						userOperationLog.setOpMethod(serviceContext.getOperationMethod());
						userOperationLog.setSystemName(serviceContext.getUserContext().getSystemName());
						userOperationLog.setUserId(serviceContext.getUserContext().getUserId());
						userOperationLog.setUserIp(serviceContext.getUserContext().getUserIp());
						
						userOperationLogDao.save(userOperationLog);
					}
				}
			}
		} catch (Exception e) {
			//记录日志出错不需要抛出异常，改成输出日志
			logger.error("error when log: " + method, new RuntimeException("持久化用户操作日志出错", e));
		}
		return result;
	}

}
